package com.alex.rankingpoint;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class Alex008ScoreRankService {

    private static final String RANK_KEY = "alex008:score:rank:withtime";

    // 选择一个足够大的倍数，确保score和timestamp不会混淆
    private static final long MULTIPLIER = 1_000_000_000_000L; // 1万亿
    private static final long MAX_TIMESTAMP = 10_000_000_000_000L; // 10万亿, 够用到2286年

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 增加/更新用户积分（分数相同则按先到者优先）
     * @param userId 用户ID
     * @param score 新的总积分（建议：外部保证是“最新积分”）
     */
    public void updateScore(String userId, long score) {
        long now = System.currentTimeMillis();
        // 复合分数: 积分部分*MULTIPLIER+（MAX_TIMESTAMP-当前时间）
        double compositeScore = score * MULTIPLIER + (MAX_TIMESTAMP - now);
        redisTemplate.opsForZSet().add(RANK_KEY, userId, compositeScore);
    }

    /**
     * 查询排行榜TopN
     * @param topN 前N名
     * @return List<Map>，每个元素有userId, score, timestamp
     */
    public List<Map<String, Object>> getTopN(int topN) {
        Set<String> users = redisTemplate.opsForZSet()
                .reverseRange(RANK_KEY, 0, topN - 1);
        if (users == null) return Collections.emptyList();

        return users.stream().map(userId -> {
            Double compositeScore = redisTemplate.opsForZSet()
                    .score(RANK_KEY, userId);
            Map<String, Object> map = new HashMap<>();
            map.put("userId", userId);
            if (compositeScore != null) {
                // 解析出score和timestamp
                long score = (long) (compositeScore / MULTIPLIER);
                long timestamp = MAX_TIMESTAMP - (long) (compositeScore % MULTIPLIER);
                map.put("score", score);
                map.put("timestamp", timestamp);
            } else {
                map.put("score", 0);
                map.put("timestamp", 0);
            }
            return map;
        }).collect(Collectors.toList());
    }

    /**
     * 查询某用户的排名和积分
     * @param userId 用户ID
     * @return Map: userId, score, rank, timestamp
     */
    public Map<String, Object> getUserRankInfo(String userId) {
        Long rank = redisTemplate.opsForZSet().reverseRank(RANK_KEY, userId);
        Double compositeScore = redisTemplate.opsForZSet().score(RANK_KEY, userId);
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        if (compositeScore != null) {
            long score = (long) (compositeScore / MULTIPLIER);
            long timestamp = MAX_TIMESTAMP - (long) (compositeScore % MULTIPLIER);
            map.put("score", score);
            map.put("timestamp", timestamp);
        } else {
            map.put("score", 0);
            map.put("timestamp", 0);
        }
        map.put("rank", rank == null ? -1 : rank + 1);
        return map;
    }

    /**
     * 删除某个用户的积分记录
     * @param userId 用户ID
     */
    public void removeUser(String userId) {
        redisTemplate.opsForZSet().remove(RANK_KEY, userId);
    }
}